Load the library
Load the dataset
Plot1(a): Trend on people who tested positive (For all the data).
#Plot to visualise trend on positive cases.
plot_positive_case <- trend_hb_daily %>%
filter (hb_name == "Scotland") %>%
ggplot()+
aes(x = date, y = daily_positive)+
geom_line()+
scale_x_date(breaks = "1 month", date_labels = "%b - %y" )+
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1))+
ggtitle("People tested positive") +
xlab("Date (Months)") +
ylab("No of Positive Cases") +
color_theme()
ggplotly(plot_positive_case)
NA
NA
Plot1(b): Trend on people who tested positive(For Past 6 months).
plot_positive_case <- trend_hb_daily %>%
filter(date >="2021-04-01") %>%
filter (hb_name == "Scotland") %>%
ggplot()+
aes(x = date, y = daily_positive)+
geom_line()+
#scale_x_date(breaks = "1 month")+
scale_x_date(breaks = "1 month", date_labels = "%b - %y" )+
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1))+
ggtitle("People tested Positive") +
xlab("Date (Months)") +
ylab("No of Positive Cases") +
color_theme()
ggplotly(plot_positive_case)
Plot1(c): Total Positive Case by neighborhood (Based on NHS Health board).
trend_hb_daily_tot <- trend_hb_daily %>%
filter(hb_name != "Scotland") %>%
group_by(hb) %>%
summarise(total_count = sum(daily_positive))
map_data <- zones_nhs_hb %>%
inner_join(trend_hb_daily_tot, by = c("code" = "hb"))
map_palette <- colorNumeric("viridis", domain = range(map_data$total_count))
map_data <- map_data %>%
arrange(total_count)
map_data <- map_data %>%
mutate(colour = map_palette(total_count))
map_data %>%
leaflet() %>%
addPolygons(
popup = ~ str_c(name, "<br>", "Positive Case = ", total_count, sep = ""),
color = ~colour
) %>%
addLegend(
position = "bottomright",
colors = ~colour,
labels = ~name
)
NA
Plot1(c): Total Positive Case by neighborhood (Based on Local Authority).
trend_la_daily_tot <- trend_la_daily %>%
group_by(ca) %>%
summarise(total_count = sum(daily_positive))
map_data <- zones_la %>%
inner_join(trend_la_daily_tot, by = c("code" = "ca"))
map_palette <- colorNumeric("viridis", domain = range(map_data$total_count))
map_data <- map_data %>%
arrange(total_count)
map_data <- map_data %>%
mutate(colour = map_palette(total_count))
map_data %>%
leaflet() %>%
addPolygons(
popup = ~ str_c(name, "<br>", "Positive Case = ", total_count, sep = ""),
color = ~colour
) %>%
addLegend(
position = "bottomright",
colors = ~colour,
labels = ~name
)
Check if the forecast data fits our existing data
# Set the training data from Jan to Aug
train <- trend %>%
filter_index("2021-01-01" ~ "2021-08-31")
# run the model on the training set
fit_train <- train %>%
model(
mean_model = MEAN(daily_positive),
arima = ARIMA(daily_positive),
snaive = SNAIVE(daily_positive)
)
forecast_test <- fit_train %>%
forecast(h = 30)
forecast_test %>%
autoplot(train, level = NULL) +
autolayer(filter_index(trend, "2021-09-01" ~.), color = "black") +
ggtitle("Forecasts for positive cases") +
xlab("Date") + ylab("Daily Positive") +
guides(colour=guide_legend(title="Forecast"))
Plot variable not specified, automatically selected `.vars = daily_positive`

Check for the accuracy of the model
The minimum RMSE is chosen.
accuracy_model <- accuracy(forecast_test, trend)
accuracy_model %>%
select(-.type) %>%
arrange(RMSE)
2 Analyse the trend on Hospitalisations:
plot_hosp <- trend_hb_daily %>%
filter(date >="2021-04-01") %>%
filter (hb_name == "Scotland") %>%
filter(!(is.na(hospital_admissions))) %>%
ggplot()+
aes(x = date, y = hospital_admissions)+
geom_col()+
scale_x_date(breaks = "1 week", date_labels = "%d - %b" )+
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1))+
ggtitle("Trend on Hospitalisations") +
xlab("Date (months)") +
ylab("No of patients admitted") +
color_theme()
ggplotly(plot_hosp)
NA
2 (b) Forecast on Hospitalisation:**
Using 6 months of data ( Two - Wave)
trend_hosp <- trend_hb_daily %>%
filter (hb_name == "Scotland") %>%
filter(date >="2021-06-01") %>%
filter(!(is.na(hospital_admissions))) %>%
select(date, hospital_admissions)
trend_hosp <- as_tsibble(trend_hosp, index = date)
fit <- trend_hosp %>%
model(
snaive = SNAIVE(hospital_admissions),
mean_model = MEAN(hospital_admissions),
arima = ARIMA(hospital_admissions),
ets = ETS(log(hospital_admissions) ~ error("M") + trend("Ad") + season("A"))
)
forecast_14days <- fit %>%
forecast(h = 14)
forecast_14days %>%
# filter(.model == "snaive") %>%
autoplot(trend_hosp, level = NULL) +
ggtitle("Forecasts for Hospital admissions cases for 2 weeks") +
xlab("Year") +
ylab("No of patients admitted") +
guides(colour = guide_legend(title = "Forecast"))+
scale_x_date(breaks = "1 month", date_labels = "%B" )+
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1))

forecast_1month <- fit %>%
fabletools::forecast(h = "1 month")
forecast_1month %>%
filter(.model %in% c("snaive","arima")) %>%
autoplot(trend_hosp, level = NULL) +
ggtitle("Forecasts for Hospitalisation for one month") +
xlab("Year") +
ylab("No of Positive Cases") +
guides(colour = guide_legend(title = "Forecast"))+
scale_x_date(breaks = "1 month", date_labels = "%B" )+
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1))

# set the training data
train <- trend_hosp %>%
filter_index("2021-06-01" ~ "2021-08-31")
# run the model on the training set
fit_train <- train %>%
model(
mean_model = MEAN(hospital_admissions),
arima = ARIMA(hospital_admissions),
snaive = SNAIVE(hospital_admissions),
ets = ETS(log(hospital_admissions) ~ error("M") + trend("Ad") + season("A"))
)
forecast_test <- fit_train %>%
forecast(h = 35)
forecast_test %>%
filter(.model %in% c("arima","snaive")) %>%
autoplot(train ) +
autolayer(filter_index(trend_hosp, "2021-06-01" ~.), color = "black") +
ggtitle("Forecasts for Hospitalisations") +
facet_wrap(~.model)+
xlab("Date") +
ylab("No of Patients admitted") +
guides(colour=guide_legend(title="Forecast"))
Plot variable not specified, automatically selected `.vars = hospital_admissions`

accuracy_model <- accuracy(forecast_test, trend_hosp)
Warning: The future dataset is incomplete, incomplete out-of-sample data will be treated as missing.
1 observation is missing at 2021-10-05
accuracy_model %>%
select(-.type) %>%
arrange(RMSE)
Plot3(a): Trend on people who tested positive (For all the data).
#Plot to visualize trend on positive cases.
plot_vaccine <- daily_vacc_hb_plot %>%
ggplot()+
aes(x = date, y = number_vaccinated)+
geom_line(aes(color = dose))+
facet_wrap(~dose)+
scale_x_date(breaks = "1 month", date_labels = "%b - %y" )+
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1))+
ggtitle("Trend on Vaccination") +
xlab("Year") +
ylab("No of Positive Cases") +
color_theme()
ggplotly(plot_vaccine)
LS0tDQp0aXRsZTogIlBIU19Db3ZpZCBBbmFseXNpcyINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCiMjIyAqKkxvYWQgdGhlIGxpYnJhcnkqKg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShoZXJlKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KGZhYmxlKQ0KbGlicmFyeShmYWJsZXRvb2xzKQ0KbGlicmFyeShmb3JlY2FzdCkNCmxpYnJhcnkodHNpYmJsZSkNCmxpYnJhcnkodHNpYmJsZWRhdGEpDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCmxpYnJhcnkobGVhZmxldCkNCmxpYnJhcnkodG1hcCkNCmBgYA0KDQojIyMgKipMb2FkIHRoZSBkYXRhc2V0KioNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCiNMb2FkIHRoZSBkYXRhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpzb3VyY2UoaGVyZSgiY2xlYW5pbmdfc2NyaXB0cy9waHNfY292aWRfY2xlYW5pbmcuUiIpKQ0KYGBgDQoNCiMjIyAqKipQbG90MShhKTogVHJlbmQgb24gcGVvcGxlIHdobyB0ZXN0ZWQgcG9zaXRpdmUgKEZvciBhbGwgdGhlIGRhdGEpLioqKg0KDQpgYGB7cn0NCiNQbG90IHRvIHZpc3VhbGlzZSB0cmVuZCBvbiBwb3NpdGl2ZSBjYXNlcy4NCnBsb3RfcG9zaXRpdmVfY2FzZSA8LSB0cmVuZF9oYl9kYWlseSAlPiUgDQogIGZpbHRlciAoaGJfbmFtZSA9PSAiU2NvdGxhbmQiKSAlPiUgDQogIGdncGxvdCgpKw0KICBhZXMoeCA9IGRhdGUsIHkgPSBkYWlseV9wb3NpdGl2ZSkrDQogIGdlb21fbGluZSgpKw0KICBzY2FsZV94X2RhdGUoYnJlYWtzID0gIjEgbW9udGgiLCBkYXRlX2xhYmVscyA9ICIlYiAtICV5IiApKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCB2anVzdCA9IDEsIGhqdXN0PTEpKSsNCiAgZ2d0aXRsZSgiUGVvcGxlIHRlc3RlZCBwb3NpdGl2ZSIpICsNCiAgeGxhYigiRGF0ZSAoTW9udGhzKSIpICsNCiAgeWxhYigiTm8gb2YgUG9zaXRpdmUgQ2FzZXMiKSArDQogIGNvbG9yX3RoZW1lKCkgDQoNCmdncGxvdGx5KHBsb3RfcG9zaXRpdmVfY2FzZSkNCg0KDQpgYGANCg0KIyMjICoqKlBsb3QxKGIpOiBUcmVuZCBvbiBwZW9wbGUgd2hvIHRlc3RlZCBwb3NpdGl2ZShGb3IgUGFzdCA2IG1vbnRocykuKioqDQoNCmBgYHtyfQ0KcGxvdF9wb3NpdGl2ZV9jYXNlIDwtIHRyZW5kX2hiX2RhaWx5ICU+JSANCiAgZmlsdGVyKGRhdGUgPj0iMjAyMS0wNC0wMSIpICU+JSANCiAgZmlsdGVyIChoYl9uYW1lID09ICJTY290bGFuZCIpICU+JSANCiAgZ2dwbG90KCkrDQogIGFlcyh4ID0gZGF0ZSwgeSA9IGRhaWx5X3Bvc2l0aXZlKSsNCiAgZ2VvbV9saW5lKCkrDQogICNzY2FsZV94X2RhdGUoYnJlYWtzID0gIjEgbW9udGgiKSsNCiAgc2NhbGVfeF9kYXRlKGJyZWFrcyA9ICIxIG1vbnRoIiwgZGF0ZV9sYWJlbHMgPSAiJWIgLSAleSIgKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgdmp1c3QgPSAxLCBoanVzdD0xKSkrDQogIGdndGl0bGUoIlBlb3BsZSB0ZXN0ZWQgUG9zaXRpdmUiKSArDQogIHhsYWIoIkRhdGUgKE1vbnRocykiKSArDQogIHlsYWIoIk5vIG9mIFBvc2l0aXZlIENhc2VzIikgKw0KICBjb2xvcl90aGVtZSgpDQoNCmdncGxvdGx5KHBsb3RfcG9zaXRpdmVfY2FzZSkNCmBgYA0KDQojIyMgKioqUGxvdDEoYyk6IFRvdGFsIFBvc2l0aXZlIENhc2UgYnkgbmVpZ2hib3Job29kIChCYXNlZCBvbiBOSFMgSGVhbHRoIGJvYXJkKS4qKioNCg0KDQpgYGB7cn0NCg0KdHJlbmRfaGJfZGFpbHlfdG90IDwtIHRyZW5kX2hiX2RhaWx5ICU+JSANCiAgZmlsdGVyKGhiX25hbWUgIT0gIlNjb3RsYW5kIikgJT4lIA0KICBncm91cF9ieShoYikgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfY291bnQgPSBzdW0oZGFpbHlfcG9zaXRpdmUpKQ0KICANCg0KbWFwX2RhdGEgPC0gem9uZXNfbmhzX2hiICU+JSANCiAgICBpbm5lcl9qb2luKHRyZW5kX2hiX2RhaWx5X3RvdCwgYnkgPSBjKCJjb2RlIiA9ICJoYiIpKQ0KICANCm1hcF9wYWxldHRlIDwtIGNvbG9yTnVtZXJpYygidmlyaWRpcyIsIGRvbWFpbiA9IHJhbmdlKG1hcF9kYXRhJHRvdGFsX2NvdW50KSkNCg0KbWFwX2RhdGEgPC0gbWFwX2RhdGEgJT4lIA0KICBhcnJhbmdlKHRvdGFsX2NvdW50KQ0KDQogbWFwX2RhdGEgPC0gbWFwX2RhdGEgJT4lIA0KICAgIG11dGF0ZShjb2xvdXIgPSBtYXBfcGFsZXR0ZSh0b3RhbF9jb3VudCkpDQogDQogIG1hcF9kYXRhICU+JQ0KICAgIGxlYWZsZXQoKSAlPiUNCiAgICBhZGRQb2x5Z29ucygNCiAgICAgIHBvcHVwID0gfiBzdHJfYyhuYW1lLCAiPGJyPiIsICAiUG9zaXRpdmUgQ2FzZSA9ICIsIHRvdGFsX2NvdW50LCBzZXAgPSAiIiksDQogICAgICBjb2xvciA9IH5jb2xvdXINCiAgICApICU+JQ0KICAgIGFkZExlZ2VuZCgNCiAgICAgIHBvc2l0aW9uID0gImJvdHRvbXJpZ2h0IiwNCiAgICAgIGNvbG9ycyA9IH5jb2xvdXIsDQogICAgICBsYWJlbHMgPSB+bmFtZQ0KICAgICkNCg0KYGBgDQoNCg0KIyMjICoqKlBsb3QxKGMpOiBUb3RhbCBQb3NpdGl2ZSBDYXNlIGJ5IG5laWdoYm9yaG9vZCAoQmFzZWQgb24gTG9jYWwgQXV0aG9yaXR5KS4qKioNCg0KDQpgYGB7cn0NCnRyZW5kX2xhX2RhaWx5X3RvdCA8LSB0cmVuZF9sYV9kYWlseSAlPiUgDQogIGdyb3VwX2J5KGNhKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9jb3VudCA9IHN1bShkYWlseV9wb3NpdGl2ZSkpDQoNCm1hcF9kYXRhIDwtIHpvbmVzX2xhICU+JSANCiAgICBpbm5lcl9qb2luKHRyZW5kX2xhX2RhaWx5X3RvdCwgYnkgPSBjKCJjb2RlIiA9ICJjYSIpKQ0KICANCm1hcF9wYWxldHRlIDwtIGNvbG9yTnVtZXJpYygidmlyaWRpcyIsIGRvbWFpbiA9IHJhbmdlKG1hcF9kYXRhJHRvdGFsX2NvdW50KSkNCg0KbWFwX2RhdGEgPC0gbWFwX2RhdGEgJT4lIA0KICBhcnJhbmdlKHRvdGFsX2NvdW50KQ0KDQogbWFwX2RhdGEgPC0gbWFwX2RhdGEgJT4lIA0KICAgIG11dGF0ZShjb2xvdXIgPSBtYXBfcGFsZXR0ZSh0b3RhbF9jb3VudCkpDQogDQptYXBfZGF0YSAlPiUNCiAgICBsZWFmbGV0KCkgJT4lDQogICAgYWRkUG9seWdvbnMoDQogICAgICBwb3B1cCA9IH4gc3RyX2MobmFtZSwgIjxicj4iLCAgIlBvc2l0aXZlIENhc2UgPSAiLCB0b3RhbF9jb3VudCwgc2VwID0gIiIpLA0KICAgICAgY29sb3IgPSB+Y29sb3VyDQogICAgKSAlPiUNCiAgICBhZGRMZWdlbmQoDQogICAgICBwb3NpdGlvbiA9ICJib3R0b21yaWdodCIsDQogICAgICBjb2xvcnMgPSB+Y29sb3VyLA0KICAgICAgbGFiZWxzID0gfm5hbWUNCiAgICApDQpgYGANCg0KDQoNCg0KIyMgKipFWFRSQSAxOiBGb3JlY2FzdCBvbiBQb3NpdGl2ZSBjYXNlczoqKg0KDQpgYGB7cn0NCiMgVGhlIGRhdGEgaXMgY2hvc2VuIGZyb20gSnVuIGFzIGl0IGlzIHRoZSBiZWdpbm5pbmcgb2Ygd2F2ZSAxIA0KdHJlbmQgPC0gdHJlbmRfaGJfZGFpbHkgJT4lIA0KICBmaWx0ZXIgKGhiX25hbWUgPT0gIlNjb3RsYW5kIikgJT4lIA0KICBmaWx0ZXIoZGF0ZSA+PSIyMDIxLTA2LTAxIikgJT4lIA0KICBzZWxlY3QoZGF0ZSwgZGFpbHlfcG9zaXRpdmUpDQoNCiMgRGF0YSBpcyBjb252ZXJ0ZWQgaW50byB0aW1lc2VyaWVzIGZvciBmb3JlY2FzdGluZw0KdHJlbmQgPC0gYXNfdHNpYmJsZSh0cmVuZCwgaW5kZXggPSBkYXRlKQ0KDQojIERpZmZlcmVudCBmb3JlY2FzdGluZyBtZXRob2RzIGFyZSB1c2VkIA0KZml0IDwtIHRyZW5kICU+JQ0KICBtb2RlbCgNCiAgICBzbmFpdmUgPSBTTkFJVkUoZGFpbHlfcG9zaXRpdmUpLA0KICAgIG1lYW5fbW9kZWwgPSBNRUFOKGRhaWx5X3Bvc2l0aXZlKSwNCiAgICBhcmltYSA9IEFSSU1BKGRhaWx5X3Bvc2l0aXZlKQ0KICApDQoNCiMgRm9yZWNhc3QgZm9yIDIgd2Vla3MgKDE0IGRheXMpDQpmb3JlY2FzdF8xNGRheXMgPC0gZml0ICU+JQ0KICBmb3JlY2FzdChoID0gMTQpDQpmb3JlY2FzdF8xNGRheXMNCmBgYA0KDQpgYGB7cn0NCmZvcmVjYXN0XzE0ZGF5cyAlPiUNCiAjZmlsdGVyKC5tb2RlbCA9PSAic25haXZlIikgJT4lDQogYXV0b3Bsb3QodHJlbmQsIGxldmVsID0gTlVMTCkgKw0KICBnZ3RpdGxlKCJGb3JlY2FzdHMgZm9yIFBvc2l0aXZlIGNhc2VzIGZvciAyIHdlZWtzIikgKw0KICB4bGFiKCJZZWFyIikgKw0KICB5bGFiKCJObyBvZiBQb3NpdGl2ZSBDYXNlcyIpICsNCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJGb3JlY2FzdCIpKSsNCiAgc2NhbGVfeF9kYXRlKGJyZWFrcyA9ICIxIG1vbnRoIiwgZGF0ZV9sYWJlbHMgPSAiJUIiICkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIHZqdXN0ID0gMSwgaGp1c3Q9MSkpDQpgYGANCg0KKipFWFRSQTogRm9yZWNhc3QgZm9yIG9uZSBtb250aDoqKg0KYGBge3J9DQpmb3JlY2FzdF8xbW9udGggPC0gZml0ICU+JQ0KICBmYWJsZXRvb2xzOjpmb3JlY2FzdChoID0gIjEgbW9udGgiKQ0KDQpmb3JlY2FzdF8xbW9udGggJT4lDQogI2ZpbHRlcigubW9kZWwgPT0gInNuYWl2ZSIpICU+JQ0KIGF1dG9wbG90KHRyZW5kLCBsZXZlbCA9IE5VTEwpICsNCiAgZ2d0aXRsZSgiRm9yZWNhc3RzIGZvciBQb3NpdGl2ZSBjYXNlcyBmb3Igb25lIG1vbnRoIikgKw0KICB4bGFiKCJZZWFyIikgKw0KICB5bGFiKCJObyBvZiBQb3NpdGl2ZSBDYXNlcyIpICsNCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJGb3JlY2FzdCIpKSsNCiAgc2NhbGVfeF9kYXRlKGJyZWFrcyA9ICIxIG1vbnRoIiwgZGF0ZV9sYWJlbHMgPSAiJUIiICkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIHZqdXN0ID0gMSwgaGp1c3Q9MSkpDQoNCmBgYA0KDQojIyAqKkNoZWNrIGlmIHRoZSBmb3JlY2FzdCBkYXRhIGZpdHMgb3VyIGV4aXN0aW5nIGRhdGEqKg0KDQpgYGB7cn0NCg0KIyBTZXQgdGhlIHRyYWluaW5nIGRhdGEgZnJvbSBKYW4gdG8gQXVnDQp0cmFpbiA8LSB0cmVuZCAlPiUNCiAgZmlsdGVyX2luZGV4KCIyMDIxLTAxLTAxIiB+ICIyMDIxLTA4LTMxIikNCg0KIyBydW4gdGhlIG1vZGVsIG9uIHRoZSB0cmFpbmluZyBzZXQgDQpmaXRfdHJhaW4gPC0gdHJhaW4gJT4lDQogIG1vZGVsKA0KICAgIG1lYW5fbW9kZWwgPSBNRUFOKGRhaWx5X3Bvc2l0aXZlKSwNCiAgICBhcmltYSA9IEFSSU1BKGRhaWx5X3Bvc2l0aXZlKSwNCiAgICBzbmFpdmUgPSBTTkFJVkUoZGFpbHlfcG9zaXRpdmUpDQogICkNCg0KZm9yZWNhc3RfdGVzdCA8LSBmaXRfdHJhaW4gJT4lIA0KICBmb3JlY2FzdChoID0gMzApDQoNCmZvcmVjYXN0X3Rlc3QgJT4lDQogIGF1dG9wbG90KHRyYWluLCBsZXZlbCA9IE5VTEwpICsNCiAgICBhdXRvbGF5ZXIoZmlsdGVyX2luZGV4KHRyZW5kLCAiMjAyMS0wOS0wMSIgfi4pLCBjb2xvciA9ICJibGFjayIpICsNCiAgICBnZ3RpdGxlKCJGb3JlY2FzdHMgZm9yIHBvc2l0aXZlIGNhc2VzIikgKw0KICAgIHhsYWIoIkRhdGUiKSArIHlsYWIoIkRhaWx5IFBvc2l0aXZlIikgKw0KICAgIGd1aWRlcyhjb2xvdXI9Z3VpZGVfbGVnZW5kKHRpdGxlPSJGb3JlY2FzdCIpKQ0KDQpgYGANCg0KIyMgKipDaGVjayBmb3IgdGhlIGFjY3VyYWN5IG9mIHRoZSBtb2RlbCoqDQoNClRoZSBtaW5pbXVtIFJNU0UgaXMgY2hvc2VuLg0KYGBge3J9DQphY2N1cmFjeV9tb2RlbCA8LSBhY2N1cmFjeShmb3JlY2FzdF90ZXN0LCB0cmVuZCkNCg0KYWNjdXJhY3lfbW9kZWwgJT4lIA0KICBzZWxlY3QoLS50eXBlKSAlPiUNCiAgYXJyYW5nZShSTVNFKQ0KYGBgDQoNCiMjICoqMiBBbmFseXNlIHRoZSB0cmVuZCBvbiBIb3NwaXRhbGlzYXRpb25zOioqDQoNCmBgYHtyfQ0KcGxvdF9ob3NwIDwtIHRyZW5kX2hiX2RhaWx5ICU+JSANCiAgZmlsdGVyKGRhdGUgPj0iMjAyMS0wNC0wMSIpICU+JSANCiAgZmlsdGVyIChoYl9uYW1lID09ICJTY290bGFuZCIpICU+JSANCiAgZmlsdGVyKCEoaXMubmEoaG9zcGl0YWxfYWRtaXNzaW9ucykpKSAlPiUgDQogIGdncGxvdCgpKw0KICBhZXMoeCA9IGRhdGUsIHkgPSBob3NwaXRhbF9hZG1pc3Npb25zKSsNCiAgZ2VvbV9jb2woKSsNCiAgc2NhbGVfeF9kYXRlKGJyZWFrcyA9ICIxIHdlZWsiLCBkYXRlX2xhYmVscyA9ICIlZCAtICViIiApKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCB2anVzdCA9IDEsIGhqdXN0PTEpKSsNCiAgZ2d0aXRsZSgiVHJlbmQgb24gSG9zcGl0YWxpc2F0aW9ucyIpICsNCiAgeGxhYigiRGF0ZSAobW9udGhzKSIpICsNCiAgeWxhYigiTm8gb2YgcGF0aWVudHMgYWRtaXR0ZWQiKSArDQogIGNvbG9yX3RoZW1lKCkNCg0KZ2dwbG90bHkocGxvdF9ob3NwKQ0KDQpgYGANCg0KDQojIyAyIChiKSBGb3JlY2FzdCBvbiBIb3NwaXRhbGlzYXRpb246KioNCg0KVXNpbmcgNiBtb250aHMgb2YgZGF0YSAoIFR3byAtIFdhdmUpDQoNCmBgYHtyfQ0KdHJlbmRfaG9zcCA8LSB0cmVuZF9oYl9kYWlseSAlPiUgDQogIGZpbHRlciAoaGJfbmFtZSA9PSAiU2NvdGxhbmQiKSAlPiUgDQogIGZpbHRlcihkYXRlID49IjIwMjEtMDYtMDEiKSAlPiUgDQogIGZpbHRlcighKGlzLm5hKGhvc3BpdGFsX2FkbWlzc2lvbnMpKSkgJT4lIA0KICBzZWxlY3QoZGF0ZSwgaG9zcGl0YWxfYWRtaXNzaW9ucykNCg0KdHJlbmRfaG9zcCA8LSBhc190c2liYmxlKHRyZW5kX2hvc3AsIGluZGV4ID0gZGF0ZSkNCg0KZml0IDwtIHRyZW5kX2hvc3AgJT4lDQogIG1vZGVsKA0KICAgIHNuYWl2ZSA9IFNOQUlWRShob3NwaXRhbF9hZG1pc3Npb25zKSwNCiAgICBtZWFuX21vZGVsID0gTUVBTihob3NwaXRhbF9hZG1pc3Npb25zKSwNCiAgICBhcmltYSA9IEFSSU1BKGhvc3BpdGFsX2FkbWlzc2lvbnMpLA0KICAgIGV0cyA9IEVUUyhsb2coaG9zcGl0YWxfYWRtaXNzaW9ucykgfiBlcnJvcigiTSIpICsgdHJlbmQoIkFkIikgKyBzZWFzb24oIkEiKSkNCiAgKQ0KDQpmb3JlY2FzdF8xNGRheXMgPC0gZml0ICU+JQ0KICBmb3JlY2FzdChoID0gMTQpDQoNCmZvcmVjYXN0XzE0ZGF5cyAlPiUNCiMgZmlsdGVyKC5tb2RlbCA9PSAic25haXZlIikgJT4lDQogYXV0b3Bsb3QodHJlbmRfaG9zcCwgbGV2ZWwgPSBOVUxMKSArDQogIGdndGl0bGUoIkZvcmVjYXN0cyBmb3IgSG9zcGl0YWwgYWRtaXNzaW9ucyBjYXNlcyBmb3IgMiB3ZWVrcyIpICsNCiAgeGxhYigiWWVhciIpICsNCiAgeWxhYigiTm8gb2YgcGF0aWVudHMgYWRtaXR0ZWQiKSArDQogIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiRm9yZWNhc3QiKSkrDQogIHNjYWxlX3hfZGF0ZShicmVha3MgPSAiMSBtb250aCIsIGRhdGVfbGFiZWxzID0gIiVCIiApKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCB2anVzdCA9IDEsIGhqdXN0PTEpKQ0KDQpgYGANCg0KDQpgYGB7cn0NCmZvcmVjYXN0XzFtb250aCA8LSBmaXQgJT4lDQogIGZhYmxldG9vbHM6OmZvcmVjYXN0KGggPSAiMSBtb250aCIpDQoNCmZvcmVjYXN0XzFtb250aCAlPiUNCiBmaWx0ZXIoLm1vZGVsICVpbiUgYygic25haXZlIiwiYXJpbWEiKSkgJT4lDQogYXV0b3Bsb3QodHJlbmRfaG9zcCwgbGV2ZWwgPSBOVUxMKSArDQogIGdndGl0bGUoIkZvcmVjYXN0cyBmb3IgSG9zcGl0YWxpc2F0aW9uIGZvciBvbmUgbW9udGgiKSArDQogIHhsYWIoIlllYXIiKSArDQogIHlsYWIoIk5vIG9mIFBvc2l0aXZlIENhc2VzIikgKw0KICBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKHRpdGxlID0gIkZvcmVjYXN0IikpKw0KICBzY2FsZV94X2RhdGUoYnJlYWtzID0gIjEgbW9udGgiLCBkYXRlX2xhYmVscyA9ICIlQiIgKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgdmp1c3QgPSAxLCBoanVzdD0xKSkNCg0KYGBgDQoNCmBgYHtyfQ0KIyAgc2V0IHRoZSB0cmFpbmluZyBkYXRhDQp0cmFpbiA8LSB0cmVuZF9ob3NwICU+JQ0KICBmaWx0ZXJfaW5kZXgoIjIwMjEtMDYtMDEiIH4gIjIwMjEtMDgtMzEiKQ0KDQojIHJ1biB0aGUgbW9kZWwgb24gdGhlIHRyYWluaW5nIHNldCANCmZpdF90cmFpbiA8LSB0cmFpbiAlPiUNCiAgbW9kZWwoDQogICAgbWVhbl9tb2RlbCA9IE1FQU4oaG9zcGl0YWxfYWRtaXNzaW9ucyksDQogICAgYXJpbWEgPSBBUklNQShob3NwaXRhbF9hZG1pc3Npb25zKSwNCiAgICBzbmFpdmUgPSBTTkFJVkUoaG9zcGl0YWxfYWRtaXNzaW9ucyksDQogICAgZXRzID0gRVRTKGxvZyhob3NwaXRhbF9hZG1pc3Npb25zKSB+IGVycm9yKCJNIikgKyB0cmVuZCgiQWQiKSArIHNlYXNvbigiQSIpKQ0KICApDQoNCmZvcmVjYXN0X3Rlc3QgPC0gZml0X3RyYWluICU+JSANCiAgZm9yZWNhc3QoaCA9IDM1KQ0KDQpmb3JlY2FzdF90ZXN0ICU+JQ0KICBmaWx0ZXIoLm1vZGVsICVpbiUgYygiYXJpbWEiLCJzbmFpdmUiKSkgJT4lDQogIGF1dG9wbG90KHRyYWluICkgKw0KICAgIGF1dG9sYXllcihmaWx0ZXJfaW5kZXgodHJlbmRfaG9zcCwgIjIwMjEtMDYtMDEiIH4uKSwgY29sb3IgPSAiYmxhY2siKSArDQogICAgZ2d0aXRsZSgiRm9yZWNhc3RzIGZvciBIb3NwaXRhbGlzYXRpb25zIikgKw0KICAgIGZhY2V0X3dyYXAofi5tb2RlbCkrDQogICAgeGxhYigiRGF0ZSIpICsgDQogICAgeWxhYigiTm8gb2YgUGF0aWVudHMgYWRtaXR0ZWQiKSArDQogICAgZ3VpZGVzKGNvbG91cj1ndWlkZV9sZWdlbmQodGl0bGU9IkZvcmVjYXN0IikpDQoNCmBgYA0KDQoNCg0KYGBge3J9DQphY2N1cmFjeV9tb2RlbCA8LSBhY2N1cmFjeShmb3JlY2FzdF90ZXN0LCB0cmVuZF9ob3NwKQ0KDQphY2N1cmFjeV9tb2RlbCAlPiUgDQogIHNlbGVjdCgtLnR5cGUpICU+JQ0KICBhcnJhbmdlKFJNU0UpDQpgYGANCg0KIyMjICoqKlBsb3QzKGEpOiBUcmVuZCBvbiBwZW9wbGUgd2hvIHRlc3RlZCBwb3NpdGl2ZSAoRm9yIGFsbCB0aGUgZGF0YSkuKioqDQoNCmBgYHtyfQ0KI1Bsb3QgdG8gdmlzdWFsaXplIHRyZW5kIG9uIHBvc2l0aXZlIGNhc2VzLg0KcGxvdF92YWNjaW5lIDwtIGRhaWx5X3ZhY2NfaGJfcGxvdCAlPiUgDQogIGdncGxvdCgpKw0KICBhZXMoeCA9IGRhdGUsIHkgPSBudW1iZXJfdmFjY2luYXRlZCkrDQogIGdlb21fbGluZShhZXMoY29sb3IgPSBkb3NlKSkrDQogIGZhY2V0X3dyYXAofmRvc2UpKw0KICBzY2FsZV94X2RhdGUoYnJlYWtzID0gIjEgbW9udGgiLCBkYXRlX2xhYmVscyA9ICIlYiAtICV5IiApKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCB2anVzdCA9IDEsIGhqdXN0PTEpKSsNCiAgZ2d0aXRsZSgiVHJlbmQgb24gVmFjY2luYXRpb24iKSArDQogIHhsYWIoIlllYXIiKSArDQogIHlsYWIoIk5vIG9mIFBvc2l0aXZlIENhc2VzIikgKw0KICBjb2xvcl90aGVtZSgpDQoNCmdncGxvdGx5KHBsb3RfdmFjY2luZSkNCmBgYA0KDQoNCg0K